package org.jeecg.demo.wx.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.jeecg.demo.wx.common.WXUserContext;
import org.jeecg.demo.wx.convert.EScheduledConvert;
import org.jeecg.demo.wx.entity.EScheduled;
import org.jeecg.demo.wx.entity.EScheduledUser;
import org.jeecg.demo.wx.enumeration.ScheduleStatusEnum;
import org.jeecg.demo.wx.event.UnReadEvent;
import org.jeecg.demo.wx.mapper.EScheduledMapper;
import org.jeecg.demo.wx.request.CreateEScheduledRequest;
import org.jeecg.demo.wx.service.IEScheduledService;
import org.jeecg.demo.wx.service.IEScheduledUserService;
import org.jeecg.demo.wx.vo.ScheduleDetailVo;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: e_scheduled
 * @Author: jeecg-boot
 * @Date: 2024-01-30
 * @Version: V1.0
 */
@Service
public class EScheduledServiceImpl extends ServiceImpl<EScheduledMapper, EScheduled> implements IEScheduledService {


    @Autowired
    private IEScheduledUserService scheduledUserService;

    @Autowired
    private ApplicationEventPublisher eventPublisher;

    @Autowired
    private ISysUserService iSysUserService;


    @Override
    public List<EScheduled> getEScheduledList(Date bdate, Date edate, String status) {
        String openId = WXUserContext.getOpenId();
        List<EScheduled> eScheduleds = this.lambdaQuery()
                .select(EScheduled::getId, EScheduled::getTitle, EScheduled::getBtime,
                        EScheduled::getEtime, EScheduled::getUrgency)
                .between(EScheduled::getBtime, bdate, edate)
                .eq(StringUtils.isNotBlank(status), EScheduled::getStatus, status)
                .eq(EScheduled::getUserid, openId).list();
        Set<String> scheduleIdSet = scheduledUserService.lambdaQuery()
                .select(EScheduledUser::getScheduledId)
                .eq(EScheduledUser::getUserId, openId)
                .list().stream().map(EScheduledUser::getScheduledId).collect(Collectors.toSet());
        eScheduleds.addAll(this.lambdaQuery().select(EScheduled::getId, EScheduled::getTitle, EScheduled::getBtime,
                                                     EScheduled::getEtime, EScheduled::getUrgency)
                                   .between(EScheduled::getBtime, bdate, edate).in(EScheduled::getId, scheduleIdSet)
                                   .eq(StringUtils.isNotBlank(status), EScheduled::getStatus, status)
                                   .eq(EScheduled::getUserid, openId).list());
        eScheduleds.sort(Comparator.comparing(EScheduled::getBtime));
        return eScheduleds;
    }

    @Override
    @Transactional
    public void add(CreateEScheduledRequest request) {
        EScheduled eScheduled = EScheduledConvert.INSTANCE.convert(request);
        this.save(eScheduled);
        String eScheduledId = eScheduled.getId();
       Set<String> userIds = new HashSet<>(request.getToUserIds());
        scheduledUserService.saveBatch(userIds.stream().map(userid -> {
            EScheduledUser scheduledUser = new EScheduledUser();
            scheduledUser.setScheduledId(eScheduledId);
            scheduledUser.setUserId(userid);
            scheduledUser.setStatus(ScheduleStatusEnum.UNREAD.getDesc());
            return scheduledUser;
        }).collect(Collectors.toList()));
          eventPublisher.publishEvent(new UnReadEvent(userIds));
    }
    @Override
    public ScheduleDetailVo queryById(String id) {
        String userId = WXUserContext.getOpenId();

        SysUser sysUser = iSysUserService.lambdaQuery()
                .select(SysUser::getRealname, SysUser::getAvatar)
                .eq(SysUser::getUsername, userId).one();

        EScheduled eScheduled = this.lambdaQuery()
                .select(EScheduled::getBtime, EScheduled::getEtime,
                         EScheduled::getContent, EScheduled::getCreateTime, EScheduled::getUrgency)
                .eq(EScheduled::getId, id).one();

        Map<String, String> map = scheduledUserService.lambdaQuery().select(EScheduledUser::getUserId, EScheduledUser::getStatus)
                .eq(EScheduledUser::getScheduledId, id).list().stream().collect(Collectors.toMap(EScheduledUser::getUserId, EScheduledUser::getStatus));
        Set<String> idSet = map.keySet();
        iSysUserService.lambdaQuery().select(SysUser::getRealname,SysUser::getUsername)
                .in(SysUser::getUsername,idSet).list()
                .forEach(user -> map.computeIfPresent(user.getUsername(), (key, value) -> user.getRealname() + "-" + value));

        return ScheduleDetailVo.builder()
                .name(sysUser.getRealname()).avatar(sysUser.getAvatar())
                .bTime(eScheduled.getBtime()).eTime(eScheduled.getEtime())
                .createdTime(eScheduled.getCreateTime()).content(eScheduled.getContent())
                .urgency(eScheduled.getUrgency()).userStatusList(new ArrayList<>(map.values()))
                .build();
    }
}
